﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Text;

namespace ONCFInstall
{
  class Program
  {
    private const int MAX_ARGS_SUPPORTED = 4;

    static void Main(string[] args)
    {
      CommandLineArgs commandArgs;

      try
      {
        commandArgs = ParseArgs(args);
      }
      catch
      {
        ShowUsage();
        return;
      }

      Utility.Output("\n===================================");
      Utility.Output("OpenNETCF ONCFInstall.exe");
      //try
      {
        CustomCABInstaller installer = new CustomCABInstaller(args[0], commandArgs);
        Utility.Output(string.Format("\tApp Name:  {0}", installer.ApplicationName));
        Utility.Output(string.Format("\tPublisher: {0}", installer.ApplicationPublisher));
        Utility.Output(string.Format("\tFiles:     {0}", installer.FileCount));
        Utility.Output(string.Format("\n\tInstalling to '{0}'", installer.InstallDirectory));
        installer.Install();
        Utility.Output("\tSuccessfully installed");
      }
      //catch (Exception ex)
      //{
      //  if (System.Diagnostics.Debugger.IsAttached)
      //  {
      //    System.Diagnostics.Debugger.Break();
      //  }

      //  Utility.Output("\tERROR:");
      //  Utility.Output(string.Format("\t{0}", ex.Message));
      //}
      Utility.Output("===================================\n");
      
    }

    private static CommandLineArgs ParseArgs(string[] argList)
    {
      // see if we have args and not too many
      if ((argList == null) || (argList.Length == 0) || (argList.Length > MAX_ARGS_SUPPORTED)) throw new Exception();

      // first arg must be a path to an existing CAB
      if (!File.Exists(argList[0])) throw new FileNotFoundException();

      CommandLineArgs args = new CommandLineArgs();

      // find skip args
      for (int i = 1; i < argList.Length; i++)
      {
        if (argList[i].IndexOf("/skip", 0) == 0)
        {
          ParseSkip(argList[i], args);
        }
        else if (argList[i].IndexOf("/replace", 0) == 0)
        {
          ParseReplace(argList[i], args);
        }
        else if (argList[i].IndexOf("/sv", 0) == 0)
        {
          args.SkipOSVersionCheck = true;
        }
        else
        {
          throw new Exception();
        }
      }

      return args;
    }

    private static void ParseSkip(string skipstring, CommandLineArgs args)
    {
      if (skipstring == null) throw new ArgumentNullException("skipstring");
      if (args == null) throw new ArgumentNullException("args");
      int colonIndex = skipstring.IndexOf(':');
      if (colonIndex < 0) throw new ArgumentException("no colon found");

      skipstring = skipstring.Substring(colonIndex + 1);
      string[] skips = skipstring.Split(new char[] { ',' });

      foreach (string skip in skips)
      {
        if (!string.IsNullOrEmpty(skip))
        {
          args.SkipFiles.Add(skip);
        }
      }
    }

    private static void ParseReplace(string replacestring, CommandLineArgs args)
    {
      if (replacestring == null) throw new ArgumentNullException("skipstring");
      if (args == null) throw new ArgumentNullException("args");
      int colonIndex = replacestring.IndexOf(':');
      if (colonIndex < 0) throw new ArgumentException("no colon found");

      replacestring = replacestring.Substring(colonIndex + 1);
      string[] replacements = replacestring.Split(new char[] { ',' });

      foreach (string replacement in replacements)
      {
        if (!string.IsNullOrEmpty(replacement))
        {
          string[] values = replacement.Split(new char[] { '|' });
          if (values.Length != 2) throw new ArgumentException();
          args.PathStringReplacements.Add(values[0], values[1]);
        }
      }

    }

    private static void ShowUsage()
    {
      Utility.Output("\n===================================");
      Utility.Output("OpenNETCF ONCFInstall.exe Sample");
      Utility.Output("-----------------------------------");
      Utility.Output("Usage:");
      Utility.Output("\tONCFInstall.exe '<path to CAB>' [/sv] [/skip:file1,file2,...,fileN] [/replace:oldString1|newString1,oldString2|newString2,...,oldStringN|newStringN]");
      Utility.Output("\nFlags:");
      Utility.Output("\t/sv : Skip OS Version Check");
      Utility.Output("\t/skip<file list> : Skip files during install");
      Utility.Output("\t/replace:<path replacements {old string|new string}> : Replace strings in installation paths");
      Utility.Output("\nExamples:");
      Utility.Output("\tONCFInstall.exe '\\MyInstaller.CAB' /sv");
      Utility.Output("\tONCFInstall.exe '\\MyInstaller.CAB'");
      Utility.Output("\tONCFInstall.exe '\\MyInstaller.CAB' /skip:file2.xml");
      Utility.Output("\tONCFInstall.exe '\\MyInstaller.CAB' /replace:\\oldpath|\\newpath");
      Utility.Output("\tONCFInstall.exe '\\MyInstaller.CAB' /skip:file2.xml /replace:\\oldpath|\\newpath");
      Utility.Output("===================================\n");
    }
  }
}
